#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curl/curl.h>
#include "config.h"
#include "token.h"
#include "stt.h"
#include <jansson.h> // 使用jansson库代替cjson

// 读取音频文件
// file: 音频文件路径
// size: 音频文件大小
// return: 音频文件内容
char* read_audio_file(const char* file, size_t* size) {
    FILE *fp = fopen(file, "rb");
    if (!fp) {
        fprintf(stderr, "无法打开音频文件: %s\n", file);
        return NULL;
    }

    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    *size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // 读取文件内容
    char* buffer = malloc(*size);
    if (!buffer) {
        fprintf(stderr, "无法分配内存\n");
        fclose(fp);
        return NULL;
    }
    fread(buffer, 1, *size, fp);
    fclose(fp);

    return buffer;
}

// 写回调函数，用于存储响应数据
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    size_t realsize = size * nmemb;
    char **response_ptr = (char**)stream;

    // 分配内存用于存储响应数据
    *response_ptr = strndup(ptr, realsize);

    return realsize;
}

// 发送请求消息
// return: 响应消息正文，NULL表示失败
char* send_request(const char* access_token, const char* audio_data, size_t size) {
    CURL *client;
    CURLcode err;
    char *url = NULL;
    char *response = NULL;

    asprintf(&url, "http://vop.baidu.com/server_api?cuid=zayuwe&token=%s", access_token);

    // 初始化libcurl
    curl_global_init(CURL_GLOBAL_ALL);

    // 初始化一个curl会话
    client = curl_easy_init();
    if (!client) {
        fprintf(stderr, "curl_easy_init() failed\n");
        free(url);
        return NULL;
    }

    // 设置请求头
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: audio/pcm;rate=16000");

    // 设置curl选项
    curl_easy_setopt(client, CURLOPT_URL, url);
    curl_easy_setopt(client, CURLOPT_POST, 1L);
    curl_easy_setopt(client, CURLOPT_POSTFIELDS, audio_data);
    curl_easy_setopt(client, CURLOPT_POSTFIELDSIZE, size);
    curl_easy_setopt(client, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(client, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(client, CURLOPT_WRITEDATA, &response);

    // 执行请求
    err = curl_easy_perform(client);
    if (err != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(err));
        curl_easy_cleanup(client);
        curl_global_cleanup();
        free(url);
        curl_slist_free_all(headers);
        return NULL;
    }

    // 清理curl会话
    curl_easy_cleanup(client);
    curl_global_cleanup();
    free(url);
    curl_slist_free_all(headers);

    return response;
}

// 处理服务器返回的响应信息
void process_response(const char* response) {
    json_error_t error;
    json_t *root = json_loads(response, 0, &error);
    if (!root) {
        fprintf(stderr, "无法解析响应消息: %s\n", error.text);
        return;
    }

    // 判断err_no字段
    json_t *err_no_json = json_object_get(root, "err_no");
    if (!json_is_integer(err_no_json)) {
        fprintf(stderr, "响应消息中缺少err_no字段\n");
        json_decref(root);
        return;
    }
    int err_no = json_integer_value(err_no_json);
    if (err_no != 0) {
        fprintf(stderr, "错误码: %d\n", err_no);
        json_decref(root);
        return;
    }

    // 获取结果
    json_t *result = json_object_get(root, "result");
    if (!json_is_array(result)) {
        fprintf(stderr, "无法获取结果\n");
        json_decref(root);
        return;
    }

    // 打印结果
    size_t index;
    json_t *value;
    json_array_foreach(result, index, value) {
        printf("识别结果: %s\n", json_string_value(value));
    }

    json_decref(root);
}

void process_audio_file(const char* filename) {
    Config config;
    if (read_config("app.json", &config) != 0) {
        fprintf(stderr, "无法读取配置文件\n");
        return;
    }

    // 获取Access Token
    char* access_token = get_access_token(config.AK, config.SK);
    if (!access_token) {
        fprintf(stderr, "无法获取Access Token\n");
        free_config(&config);
        return;
    }

    // 读取音频文件
    size_t size;
    char* audio_data = read_audio_file(filename, &size);
    if (!audio_data) {
        fprintf(stderr, "无法读取音频文件\n");
        free(access_token);
        free_config(&config);
        return;
    }

    // 调用百度语音识别API
    char* response = send_request(access_token, audio_data, size);
    if (!response) {
        fprintf(stderr, "无法发送请求\n");
        free(audio_data);
        free(access_token);
        free_config(&config);
        return;
    }

    // 处理响应消息
    process_response(response);

    // 释放内存
    free(response);
    free(audio_data);
    free(access_token);
    free_config(&config);
}